﻿
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using EMRApi.LogAttribute;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using LogForParameter.Model.Models;

namespace EMRApi.LogAttribute
{
    /// <summary>
    /// 过滤器
    /// </summary>
    public class OperateTrackAttribute : IAsyncActionFilter, IAsyncResultFilter
    {
        private readonly IConfiguration _configuration;
        private readonly VillageOfficial _test;
        /// <summary>
        /// 自定义参数
        /// </summary>
        public string msg { get; set; }
        /// <summary>
        /// 初始化时填入类的说明
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="test"></param>
        public OperateTrackAttribute(IConfiguration configuration, VillageOfficial test)
        {
            _configuration = configuration;
            _test = test;
        }
        private static readonly string key = "enterTime";
        /// <summary>
        /// /// 在请求开始执行，增加过滤条件
        /// </summary>
        /// <param name="actionContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext actionContext, ActionExecutionDelegate cancellationToken)
        {
            //if (SkipLogging(actionContext))//是否该类标记为NoLog
            //{
            //    return base.OnActionExecutionAsync(actionContext, cancellationToken);

            //}
            //记录进入请求的时间
            //actionContext.HttpContext.Request.EnableBuffering(0, 3000);//可以读取流中的数据
            //var syncIOFeature = actionContext.HttpContext.Features.Get<IHttpBodyControlFeature>();
            //if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; }
            actionContext.HttpContext.Items[key] = DateTime.Now.ToBinary();
            await cancellationToken();
        }
        /// <summary>
        /// 在请求执行完后 记录请求的数据以及返回数据
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <param name="next">下一个结果</param>
        /// <returns></returns>
        public async Task OnResultExecutionAsync(ResultExecutingContext actionExecutedContext, ResultExecutionDelegate next)
        {
            await next();
            actionExecutedContext.HttpContext.Response.OnCompleted(() =>
            {
                actionExecutedContext.HttpContext.Request.Body.Position = 0;
                //var syncIOFeature = actionExecutedContext.HttpContext.Features.Get<IHttpBodyControlFeature>();
                //if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; }
                object beginTime = null;
                if (actionExecutedContext.HttpContext.Items.TryGetValue(key, out beginTime))
                {
                    DateTime time = DateTime.FromBinary(Convert.ToInt64(beginTime));
                    //actionExecutedContext.HttpContext.Request.EnableBuffering(0, 3000);//可以读取流中的数据
                    HttpRequest request = actionExecutedContext.HttpContext.Request;
                    string token = request.Headers["HospitalId"];
                    string userId = request.Headers["UserId"];
                    string depId = request.Headers["departmentId"];
                    var resultObj = actionExecutedContext.Result; //"Value":{ "ResultStatus":"200","Msg":"好的","ResultData":[],"RecordSn":null}
                    string resultjson = Newtonsoft.Json.JsonConvert.SerializeObject(actionExecutedContext.Result);
                    string regstring= "(?<=\"Value\":).+(?=,\"Format)";
                    var regex = new System.Text.RegularExpressions.Regex(regstring);
                   var data= regex.Match(resultjson)?.Value;
                    //YB_PUBLIC_APILOG apiActionLog = new YB_PUBLIC_APILOG
                    //{
                    //    //获取action名称 
                    //    ACTIONNAME = actionExecutedContext.ActionDescriptor.RouteValues["Action"],
                    //    //获取Controller 名称
                    //    CONTROLLERNAME = actionExecutedContext.ActionDescriptor.RouteValues["Controller"],
                    //    //获取action开始执行的时间
                    //    ENTERTIME = time,
                    //    //获取执行action的耗时
                    //    COSTTIME = Convert.ToDecimal((DateTime.Now - time).TotalMilliseconds),
                    //    NAVIGATOR = request.Protocol,
                    //    TOKEN = token,
                    //    USERID = userId,
                    //    //获取用户token
                    //    //userId = "token",
                    //    //获取访问的ip
                    //    IP =actionExecutedContext.HttpContext.Connection.RemoteIpAddress.ToString(),
                    //    BROWSER = request.Headers["User-Agent"].ToString().Substring(0, 49),
                    //    //USERHOSTNAME = request.UserHostName,
                    //    //URLREFERRER = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "",
                    //    //BROWSER = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type,
                    //    //获取request提交的参数
                    //    PARAMATERS = GetRequestValues(actionExecutedContext).Result,
                    //    //获取response响应的结果
                    //    EXCUTERESULT = data,
                    //    STATE = 1,
                    //    COMMENTS = string.IsNullOrEmpty(msg) ? depId : msg,
                    //    REQUESTURI = request.Host.Value+request.Path.ToUriComponent()
                    //};
                    //if (apiActionLog.EXCUTERESULT.Length > 20 && apiActionLog.EXCUTERESULT.Substring(0, 19).IndexOf("\"200\"") < 0)
                    //    apiActionLog.STATE = 2;
                    //if (apiActionLog.EXCUTERESULT.Length > 2999)
                    //    apiActionLog.EXCUTERESULT = "";
                    //if (apiActionLog.PARAMATERS.Length > 2999)
                    //    apiActionLog.PARAMATERS = "";
                    //try
                    //{
                    //    //decimal max = _test.PUBLIC_APILOGs.Max(m => m.APILOGID) + 1;
                    //    //apiActionLog.APILOGID = max;
                    //    _test.YB_PUBLIC_APILOGs.Add(apiActionLog);
                    //    _test.SaveChanges();
                    //}
                    //catch (DbUpdateConcurrencyException ex)
                    //{

                    //}
                    //catch (Exception ex)
                    //{

                    //}
                }
                return Task.CompletedTask;
            });
        }
        //public override void OnActionExecuting(ActionExecutingContext context)
        //{
        //    var syncIOFeature = context.HttpContext.Features.Get<IHttpBodyControlFeature>();
        //    if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; }
        //}
        /// <summary>
        /// 读取request 的提交内容
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <returns></returns>
        public async Task<string> GetRequestValues(ResultExecutingContext actionExecutedContext)
        {
            try
            {
                //Stream stream = actionExecutedContext.HttpContext.Request.Body;
                //Encoding encoding = Encoding.UTF8;
                /*
                    这个StreamReader不能关闭，也不能dispose
                    因为关掉后，后面的管道  或拦截器就没办法读取了
                */
                var reader = new StreamReader(actionExecutedContext.HttpContext.Request.Body);
                string result = await reader.ReadToEndAsync();
                if (string.IsNullOrEmpty(result))
                {
                    result = reader.ReadToEnd();
                }
                /*
                这里也要注意：   stream.Position = 0;
                当你读取完之后必须把stream的位置设为开始
                因为request和response读取完以后Position到最后一个位置，交给下一个方法处理的时候就会读不到内容了。
                */
                actionExecutedContext.HttpContext.Request.Body.Position = 0;
                return result;
            }
            catch (Exception)
            {
                return "";
            }
        }


        /// <summary>
        /// 读取action返回的result
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <returns></returns>
        public string GetResponseValues(ResultExecutingContext actionExecutedContext)
        {
            if (actionExecutedContext.HttpContext.Response != null)
            {
                if (actionExecutedContext.HttpContext.Response.Body == null)

                    return "";
                //Stream stream = actionExecutedContext.HttpContext.Response..AsStream();
                Encoding encoding = Encoding.UTF8;
                /*
                这个StreamReader不能关闭，也不能dispose
                因为关掉后，后面的管道  或拦截器就没办法读取了
                */
                //var reader = new StreamReader(stream, encoding);
                //string result = reader.ReadToEnd();
                string result = "";
                /*
                这里也要注意：   stream.Position = 0; 
                当你读取完之后必须把stream的位置设为开始
                因为request和response读取完以后Position到最后一个位置，交给下一个方法处理的时候就会读不到内容了。
                */
                //stream.Position = 0;
                return result;
            }
            else
            {
                return actionExecutedContext.Result.ToString();
            }
        }
        /// <summary>
        /// 不需要登陆的地方加个特性
        /// </summary>
        public class NoSignAttribute : Attribute { }
    }

}